package com.fsm.system.serviceImpl;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson2.JSONObject;
import com.fsm.common.tools.Result.Result;
import com.fsm.common.tools.util.Md5Utils;
import com.fsm.system.entity.TRoleMenu;
import com.fsm.system.entity.TSystemMenu;
import com.fsm.system.entity.excelbo.SystemMenuBo;
import com.fsm.system.entity.excelbo.SystemUserBo;
import com.fsm.system.entity.table.TSystemUserTable;
import com.fsm.system.entity.table.TRoleMenuTable;
import com.fsm.system.entity.table.TSystemMenuTable;
import com.fsm.system.mapper.TRoleMenuMapper;
import com.fsm.system.mapper.TSystemMenuMapper;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.util.CollectionUtil;
import com.mybatisflex.core.util.StringUtil;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.fsm.system.entity.TSystemUser;
import com.fsm.system.mapper.SystemUserMapper;
import com.fsm.system.service.TSystemUserService;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 *  服务层实现。
 *
 * @author 翻山鸣
 * @since 2024/04/20
 */
@Service
public class TTSystemUserServiceImpl extends ServiceImpl<SystemUserMapper, TSystemUser> implements TSystemUserService {

    @Autowired
    private TSystemMenuMapper tSystemMenuMapper;

    @Autowired
    private TRoleMenuMapper tRoleMenuMapper;

    /**
     * 公共整合查询条件
     * @param tSystemUser
     * @return
     */
    private static QueryWrapper getSelectQueryWrapper(TSystemUser tSystemUser){
        QueryWrapper queryWrapper = new QueryWrapper();
        if(StringUtil.isNotBlank(tSystemUser.getLoginName())){
            queryWrapper.where(TSystemUserTable.T_SYSTEM_USER.LOGIN_NAME.eq(tSystemUser.getLoginName()));
        }
        queryWrapper.orderBy(TSystemUserTable.T_SYSTEM_USER.ID.desc());
        return queryWrapper;
    }

    /**
     * 根据token获取用户
     *
     * @param
     * @return
     */
    @Override
    public Result getUserInfo() throws Exception {
        TSystemUser user = (TSystemUser) StpUtil.getSession().get("systemUser");
        JSONObject map = new JSONObject();
        List<String> roles = new ArrayList<>();
        roles.add("admin");
        map.put("roles",roles);
        map.put("introduction","我是" + user.getLoginName());
        map.put("avatar","https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
        map.put("name",user.getLoginName());
        //根据用户查询用户菜单
        QueryWrapper roleMenuQueryWrapper = new QueryWrapper();
        roleMenuQueryWrapper.where(TRoleMenuTable.T_ROLE_MENU.ROLE_ID.eq(user.getRoleId()));
        List<TRoleMenu> tRoleMenuList = tRoleMenuMapper.selectListByQuery(roleMenuQueryWrapper);
        List<String> menuIds = new ArrayList<>();
        for(TRoleMenu tRoleMenu : tRoleMenuList){
            menuIds.add(tRoleMenu.getMenuId());
        }
        //如果菜单ID存在
        if(CollectionUtil.isNotEmpty(menuIds)){
            //获取相应的菜单
            QueryWrapper menuQueryWrapper = new QueryWrapper();
            menuQueryWrapper.where(TSystemMenuTable.T_SYSTEM_MENU.ID.in(menuIds));
            List<TSystemMenu> menuList = tSystemMenuMapper.selectListByQuery(menuQueryWrapper);
            List<SystemMenuBo> systemMenuBoList = new ArrayList<>();
            for(TSystemMenu tSystemMenu : menuList){
                if(StringUtil.isBlank(tSystemMenu.getPid())){
                    if(!tSystemMenu.getPath().equals("/")) {
                        SystemMenuBo systemMenuBo = new SystemMenuBo();
                        systemMenuBo.setId(tSystemMenu.getId());
                        systemMenuBo.setName(tSystemMenu.getTitle());
                        systemMenuBo.setHidden(false);
                        systemMenuBo.setRedirect("");
                        systemMenuBo.setComponent("Layout");
                        HashMap<String, Object> meta = new HashMap<>();
                        meta.put("icon", tSystemMenu.getIcon());
                        meta.put("title", tSystemMenu.getTitle());
                        systemMenuBo.setMeta(meta);
                        systemMenuBo.setPath(tSystemMenu.getPath());
                        List<SystemMenuBo> children = routerMenu(tSystemMenu, menuList);
                        if (CollectionUtil.isNotEmpty(children)) {
                            systemMenuBo.setChildren(children);
                        }
                        systemMenuBoList.add(systemMenuBo);
                    }
                }
            }
            map.put("menuList",systemMenuBoList);
        }else{
            map.put("menuList",new ArrayList<>());
        }
        return Result.ok(map.toJSONString());
    }

    public List<SystemMenuBo> routerMenu(TSystemMenu tSystemMenu,List<TSystemMenu> menuList){
        List<SystemMenuBo> systemMenuBoList = new ArrayList<>();
        for(TSystemMenu tSystemMenuOne : menuList){
            if(StringUtil.isNotBlank(tSystemMenuOne.getPid()) && tSystemMenuOne.getPid().equals(tSystemMenu.getId())){
                SystemMenuBo systemMenuBo = new SystemMenuBo();
                systemMenuBo.setId(tSystemMenuOne.getId());
                systemMenuBo.setName(tSystemMenuOne.getTitle());
                systemMenuBo.setHidden(false);
                systemMenuBo.setRedirect("");
                systemMenuBo.setPath(tSystemMenuOne.getPath());
                systemMenuBo.setParent(tSystemMenuOne.getPid());
                systemMenuBo.setComponent(tSystemMenuOne.getFilePath());
                HashMap<String,Object> meta = new HashMap<>();
                meta.put("icon",tSystemMenuOne.getIcon());
                meta.put("title",tSystemMenuOne.getTitle());
                systemMenuBo.setMeta(meta);
                List<SystemMenuBo> children = routerMenu(tSystemMenuOne,menuList);
                if(CollectionUtil.isNotEmpty(children)){
                    systemMenuBo.setChildren(children);
                }else{
                    systemMenuBo.setAffix(true);
                }
                systemMenuBoList.add(systemMenuBo);
            }
        }
        return systemMenuBoList;
    }

    /**
     * 添加系统用户
     *
     * @param
     * @return
     */
    @Override
    public Result addSystemUser(TSystemUser tSystemUser) throws Exception {
        tSystemUser.setPassword(Md5Utils.code("123456"));
        int sign = this.getMapper().insert(tSystemUser);
        if(sign == 0){
            return Result.fail("添加系统用户失败");
        }
        return Result.ok();
    }

    /**
     * 删除系统用户
     *
     * @param
     * @return
     */
    @Override
    public Result deleteSystemUser(TSystemUser tSystemUser) throws Exception {
        int sign = this.getMapper().deleteById(tSystemUser.getId());
        if(sign == 0){
            return Result.fail("删除系统用户失败");
        }
        return Result.ok();
    }

    /**
     * 更新系统用户
     *
     * @param tSystemUser
     * @return
     */
    @Override
    public Result updateSystemUser(TSystemUser tSystemUser) throws Exception {
        TSystemUser tSystemUserOld = this.getMapper().selectOneById(tSystemUser.getId());
        if(tSystemUser.getPassword() != null && !tSystemUserOld.getPassword().equals(tSystemUser.getPassword())){
            tSystemUser.setPassword(Md5Utils.code(tSystemUser.getPassword()));
        }
        int sign = this.getMapper().update(tSystemUser);
        if(sign == 0){
            return Result.fail("更新系统用户失败");
        }
        return Result.ok();
    }

    /**
     * 分页查询系统用户
     *
     * @param
     * @return 分页对象
     */
    @Override
    public Result pageSystemUser(TSystemUser tSystemUser) throws Exception {
        QueryWrapper queryWrapper = getSelectQueryWrapper(tSystemUser);
        Page<TSystemUser> systemUserPage = this.getMapper().paginateWithRelations(tSystemUser.getPage(), tSystemUser.getLimit(),queryWrapper);
        return Result.ok(systemUserPage.getRecords(),systemUserPage.getTotalRow());
    }

    /**
     * 通过ID查询系统管理ID
     *
     * @param
     * @return 分页对象
     */
    @Override
    public Result getSystemUserList(TSystemUser tSystemUser) throws Exception{
        QueryWrapper queryWrapper = getSelectQueryWrapper(tSystemUser);
        List<TSystemUser> TSystemUserList = this.getMapper().selectListWithRelationsByQuery(queryWrapper);
        return Result.ok(TSystemUserList, TSystemUserList.size());
    }

    /**
     * 通过ID查询系统管理ID
     *
     * @param
     * @return 分页对象
     */
    @Override
    public Result getSystemUserById(TSystemUser tSystemUser) throws Exception{
        TSystemUser tSystemUserOne = this.getMapper().selectOneWithRelationsById(tSystemUser.getId());
        return Result.ok(tSystemUserOne);
    }

    /**
     * 通过用户ID获取菜单
     *
     * @param
     * @return 分页对象
     */
    @Override
    public Result getMenuByUserId(TSystemUser tSystemUser) throws Exception {
        TSystemUser tSystemUserOne = this.getMapper().selectOneById(tSystemUser.getId());
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.where(TRoleMenuTable.T_ROLE_MENU.ROLE_ID.eq(tSystemUserOne.getRoleId()));
        List<TRoleMenu> tRoleMenuList = tRoleMenuMapper.selectListByQuery(queryWrapper);
        //遍历
        List<String> menuList = new ArrayList<>();
        for(TRoleMenu tRoleMenuOne : tRoleMenuList){
            menuList.add(tRoleMenuOne.getMenuId());
        }
        if(CollectionUtil.isNotEmpty(menuList)){
            QueryWrapper MenuQueryWrapper = new QueryWrapper();
            MenuQueryWrapper.where(TSystemMenuTable.T_SYSTEM_MENU.ID.in(menuList));
            List<TSystemMenu> menus = tSystemMenuMapper.selectListByQuery(MenuQueryWrapper);
            List<TSystemMenu> topMenus = new ArrayList<>();
            for(TSystemMenu tSystemMenu : menus){
                if(tSystemMenu.getPid() == null){
                    List<TSystemMenu> tSystemMenuListOne = getChildren(menus,tSystemMenu.getId());
                    if(CollectionUtil.isNotEmpty(tSystemMenuListOne)){
                        tSystemMenu.setChildren(tSystemMenuListOne);
                    }
                    topMenus.add(tSystemMenu);
                }
            }
            return Result.ok(topMenus);
        }else{
            return Result.ok();
        }
    }

    /**
     * 导出用户信息
     *
     * @param
     * @return 分页对象
     */
    @Override
    public Result uploadUser(TSystemUser tSystemUser, HttpServletResponse response) throws Exception {
        //准备需要输出的数据 调用业务层，获得所有需要导出的数据
        QueryWrapper queryWrapper = getSelectQueryWrapper(tSystemUser);
        List<TSystemUser> tSystemUserList = this.getMapper().selectListWithRelationsByQuery(queryWrapper);
        List<SystemUserBo> systemUserBos = new ArrayList<>();
        for (TSystemUser tSystemUserOne : tSystemUserList){
            SystemUserBo systemUserBo = new SystemUserBo();
            BeanUtils.copyProperties(tSystemUserOne,systemUserBo);
            systemUserBos.add(systemUserBo);
        }
        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("用户信息", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        OutputStream outputStream = response.getOutputStream();
        EasyExcel.write(outputStream, SystemUserBo.class).sheet("模板").doWrite(systemUserBos);
        return Result.ok();
    }

    private List<TSystemMenu> getChildren(List<TSystemMenu> menus,String id){
        List<TSystemMenu> tSystemMenuList = new ArrayList<>();
        for(TSystemMenu tSystemMenu : menus){
            if(tSystemMenu.getPid() != null && tSystemMenu.getPid().equals(id)){
                List<TSystemMenu> tSystemMenuListOne = getChildren(menus,tSystemMenu.getId());
                if(CollectionUtil.isNotEmpty(tSystemMenuListOne)){
                    tSystemMenu.setChildren(tSystemMenuListOne);
                }
                tSystemMenuList.add(tSystemMenu);
            }
        }
        return tSystemMenuList;
    }

}
